/*
 * Open LiveReplay Server - Live replay server for Supreme Commander
 * 
 * Copyright (C) 2009, 2009 Open LiveReplay Server Project
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details:
 * http://www.gnu.org/copyleft/lesser.html#TOC3
 */
package net.galacticwar.lua;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.util.List;
/**
 * 
 * A very basic Java implementation of a LUA parser.
 * 
 * @author Yoann Meste (aka Mancer)
 *
 */
public class LuaParser {

	public static LuaTable readLua(File file) throws IOException{
		if (file==null) {
			throw new NullPointerException("File must not be null");
		}
		
		if (file.exists() == false) {
			throw new FileNotFoundException("File doesn't exists");
		}

		BufferedReader reader = new BufferedReader(new FileReader(file));
		LuaTable table = readLua(reader);
		
		reader.close();
		
		return table;
	
	}
	
	public static LuaTable readLua(Reader reader) throws IOException{
		StreamTokenizer st = new StreamTokenizer(reader);
        st.wordChars('_', '_');
        st.ordinaryChars(0, ' ');
        st.eolIsSignificant(false);

		return readLua(st);
	}

	
	private static LuaTable readLua(StreamTokenizer st) throws IOException{

		LuaTable table = new LuaTable();
		LuaPair currentPair = new LuaPair();
		
        
        boolean comment = false;

        while (true) {
        	int token = st.nextToken();
            switch (token) {
            case StreamTokenizer.TT_NUMBER:
                if (comment) continue;
                currentPair.push(st.nval);
                break;
                
            case StreamTokenizer.TT_WORD:
                if (comment) continue;
   
                String word = st.sval;
                if (word.equals("FLOAT")) {
					st.nextToken();
					st.nextToken();
					float val = (float) st.nval;
					st.nextToken();
					st.nextToken();
					st.nextToken();
					currentPair.push(val);
				}
                else if (word.equals("BOOLEAN")) {
					st.nextToken();
					st.nextToken();
					st.nextToken();
					boolean val = Boolean.parseBoolean(st.sval);
					st.nextToken();
					st.nextToken();
					currentPair.push(val);
				}
                else if (word.equals("STRING")) {
					st.nextToken();
					st.nextToken();
					st.nextToken();
					String val = st.sval;
					st.nextToken();
					st.nextToken();
					currentPair.push(val);
				}
                else if (word.equals("VECTOR3")) {
                	LuaVector3 vector3 = new LuaVector3(st);
                	currentPair.push(vector3);
				}
                else if (word.equals("RECTANGLE")) {
                	LuaRectangle rect = new LuaRectangle(st);
                	currentPair.push(rect);
				}

                
                else if (word.equals("GROUP")) {

                }

                else{
                	currentPair.push(word);
                }

                
                break;
                
            case StreamTokenizer.TT_EOL:
            	if (currentPair!= null && currentPair.isEmpty()==false) {
            		table.add(currentPair);
            		currentPair = new LuaPair();
				}
           		comment = false;
            	break;
            	
            case StreamTokenizer.TT_EOF:
            	return table;
            	
            case '=':
            	currentPair.setEqual(true);
            	break;

            case '{':
            	List<LuaPair> list = readLua(st);
            	currentPair.push(list);
            	break;
            	
            case '}':
            	if ( currentPair.isEmpty()==false) {
            		table.add(currentPair);
				}
            	currentPair = null;
            	return table;


            case ',':
            	if (currentPair.isEmpty()==false) {
            		table.add(currentPair);
				}
            	currentPair = new LuaPair();
            	break;
            	
            case '"':
                if (comment) continue;
                currentPair.push(st.sval);
                break;
                
	        case '\'':
	        	if (comment) continue;
                // A single-quoted string was found; sval contains the contents
	        	currentPair.push(st.sval);
	        	break;

            case '#':
            	comment = true;
            	break;
           }
        }
	}
}
